package com.atm.thirdplt.component;

import com.alibaba.fastjson.JSONObject;
import com.atm.thirdplt.common.constant.Constants;
import com.atm.thirdplt.common.core.domain.entity.AnesAnesthesiaPlan;
import com.atm.thirdplt.common.core.domain.entity.AnesOperationMaster;
import com.atm.thirdplt.common.core.domain.entity.AtmOperationScheduleMid;
import com.atm.thirdplt.common.core.domain.his.*;
import com.atm.thirdplt.common.core.domain.lis.LisLabResult;
import com.atm.thirdplt.common.core.domain.lis.LisLabTestMaster;
import com.atm.thirdplt.common.utils.DateUtils;
import com.atm.thirdplt.common.utils.StringUtils;
import com.atm.thirdplt.common.utils.spring.SpringUtils;
import com.atm.thirdplt.common.utils.uuid.IdUtils;
import com.atm.thirdplt.service.IHisInfQueryService;
import com.atm.thirdplt.service.IHisInfService;
import com.atm.thirdplt.service.ILisInfService;
import com.atm.thirdplt.service.IScheduleSyncControllerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName HisDataHandler
 * @Description 医院数据同步中间处理业务逻辑类
 * @Author wenyf
 * @Version 1.0
 **/
@Component
public class HisDataHandler {

    private static final Logger log = LoggerFactory.getLogger(HisDataHandler.class);

    @Autowired
    private IHisInfService hisInfService;

    @Value("${interface.type}")
    private String invokType;

    @Autowired
    private ILisInfService lisInfService;

    @Autowired
    private IScheduleSyncControllerService scheduleSyncControllerService;


    /**
     * 同步科室字典数据信息
     */
    public void syncDeptDict() {

        // 1、获取His科室字典数据
        List<HisDeptDict> deptList = getDynamicService().selDeptDic();

        if (CollectionUtils.isEmpty(deptList)) {
            log.info("no depts data !");
            return;
        }

        // 2、删除mongo库数据
        hisInfService.delDeptMongo();

        // 3、保存到mongo库中
        hisInfService.saveDeptDictMongo(deptList);
        deptList = deptList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                // 利用 TreeSet 的排序去重构造函数来达到去重元素的目的
                () -> new TreeSet<>(Comparator.comparing(HisDeptDict::getDeptCode))), ArrayList::new));

        // 利用set的特性去重
        Set<HisDeptDict> mHashSet = new LinkedHashSet<>(deptList);
        deptList = new ArrayList<>(mHashSet);
        handleDeptInf(deptList);

        log.info("sync depts success !");
    }

    private void handleDeptInf(List<HisDeptDict> deptList) {
        List<HisDeptDict> list = hisInfService.selDeptLocal();
        List<HisDeptDict> uptList = new ArrayList<>();
        List<HisDeptDict> intList = new ArrayList<>();
        Map<String, HisDeptDict> deptMap = new HashMap<>();
        for (HisDeptDict dept : list) {
            deptMap.put(dept.getDeptCode(), dept);
        }
        for (HisDeptDict dept : deptList) {
            if (deptMap.get(dept.getDeptCode()) != null) {
                uptList.add(dept);
            } else {
                intList.add(dept);
            }
        }

        // 4、删除本地库中数据,因为是全量替换
        hisInfService.uptHisDept(uptList);

        // 5、保存当前最新的数据
        hisInfService.saveDept(intList);
    }

    /**
     * 同步工作人员字典数据信息
     */
    public void syncUsers() {
        // 1、获取His人员字典数据
        List<HisUsers> userList = getDynamicService().selHisUsers();

        // 2、删除mongo库数据
        hisInfService.delUserMongo();

        // 3、保存到mongo库中
        hisInfService.saveUsersMongo(userList);

        userList = userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                // 利用 TreeSet 的排序去重构造函数来达到去重元素的目的
                () -> new TreeSet<>(Comparator.comparing(HisUsers::getUserId))), ArrayList::new));

        // 跟本地数据进行比对处理
        // 利用set的特性去重
        Set<HisUsers> mHashSet = new LinkedHashSet<>(userList);
        userList = new ArrayList<>(mHashSet);
        handleUserInf(userList);

        log.info("schedule users success !");
    }

    private void handleUserInf(List<HisUsers> userList) {
        List<HisUsers> list = hisInfService.selUsersLocal();
        List<HisUsers> uptList = new ArrayList<>();
        List<HisUsers> intList = new ArrayList<>();
        Map<String, HisUsers> userMap = new HashMap<>();
        for (HisUsers user : list) {
            userMap.put(user.getUserId(), user);
        }
        HisUsers temp;
        for (HisUsers user : userList) {
            temp = userMap.get(user.getUserId());
            if (temp != null) {
                if (temp.getSyncFlag() != null) {
                    if (Constants.USER_SYNC_YES == temp.getSyncFlag()) {
                        uptList.add(user);
                    }
                } else {
                    uptList.add(user);
                }
            } else {
                intList.add(user);
            }
        }

        // 4、删除本地库中数据,因为是全量替换
        hisInfService.uptHisUser(uptList);

        // 5、保存当前最新的数据
        hisInfService.saveUsers(intList);
    }

    private Map<String, HisOperationSchedule> getOperScheMap(String startTime, String endTime) {
        // 开始时间向前推移1个月，避免某个手术修改手术时间导致匹配不到，插入报主键重复
        DateUtils.addMonths(DateUtils.parseDate(startTime), -1);
        List<HisOperationSchedule> list = hisInfService.selOpertScheleLocal(startTime, endTime);
        Map<String, HisOperationSchedule> operScheMap = new HashMap<>();
        for (HisOperationSchedule operSche : list) {
            operScheMap.put(operSche.getPatientId() + "|" + operSche.getVisitId() + "|" + operSche.getScheduleId(),
                    operSche);
        }
        return operScheMap;
    }

    private synchronized void handleOperSche(String startTime, String endTime,
                                             List<HisOperationSchedule> operScheList) {
        // 预约表处理集合定义
        List<HisOperationSchedule> uptOperScheList = new ArrayList<>();
        List<HisOperationSchedule> intOperScheList = new ArrayList<>();
        //Map<String, HisOperationSchedule> operScheLocalMap = getOperScheMap(startTime, endTime);
        String patId = null;
        String visitId = null;
        String scheId = null;

        List<HisOperationSchedule> realList = new ArrayList<>();

        // 声明手术名称信息、病人在院住院信息、病人基本信息集合
        List<HisScheduledOperationName> scheOperNameListHis = new ArrayList<>();
        List<HisPatsInHospital> patInHosListHis = new ArrayList<>();
        Set<String> patIdSet = new HashSet<>();
        HisOperationSchedule localBean;
        List<HisScheduledOperationName> operNameTemp;
        for (HisOperationSchedule openBean : operScheList) {
            // 根据His数据查询本地数据，做比对校验
            localBean = hisInfService.selOperSche(openBean.getPatientId(),openBean.getVisitId(),openBean.getScheduleId());
            patId = openBean.getPatientId();
            patIdSet.add(patId);
            visitId = openBean.getVisitId();
            scheId = openBean.getScheduleId();

            // 判断筛选预约申请信息
            if (localBean != null && localBean.getState() != null) {
//                uptOperScheList.add(openBean);
                // 如果状态为0,才能进行更新
                if (Constants.OPER_SCHE_NEW == localBean.getState()) {
                    uptOperScheList.add(openBean);
                }else{
                    log.info("the oper  update");
                    log.info("his data:" + JSONObject.toJSONString(openBean));
                }
            } else {
                if(StringUtils.isEmpty(openBean.getStatus())){
                    log.info("status null data:" + JSONObject.toJSONString(openBean));
                    openBean.setStatus("N");
                }
                intOperScheList.add(openBean);
            }

            // 对应查询手术名称信息
            operNameTemp = getDynamicService().selScheOperNameHis(patId, visitId, scheId);
            log.info("operNameTemp data:" + JSONObject.toJSONString(operNameTemp));
            if(!CollectionUtils.isEmpty(operNameTemp)){
                int i = 1;
                for (HisScheduledOperationName his:operNameTemp
                ) {
                    his.setOperationNo(String.valueOf(i));
                    i++;
                }
                scheOperNameListHis.addAll(operNameTemp);
            }

        }

        scheOperNameListHis = scheOperNameListHis.stream().collect(Collectors.collectingAndThen(Collectors.
                toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getPatientId() + ";" + o.getVisitId() + ";" + o.getScheduleId() + ";" + o.getOperationNo()))), ArrayList::new));

        log.info("opername----"+scheOperNameListHis.toString());

        // 处理麻醉本地库手术预约信息
        if (!CollectionUtils.isEmpty(uptOperScheList)) {
            hisInfService.uptOperScheLocal(uptOperScheList);
        }
        if (!CollectionUtils.isEmpty(intOperScheList)) {
            hisInfService.saveOperScheLocal(intOperScheList);
        }

        List<String> patIdList = new ArrayList<>(patIdSet);
        // 对应查询在院病人住院信息
        patInHosListHis = getDynamicService().selPatInHosHis(patIdList);

        // 处理手术名称数据
        handleScheOperName(scheOperNameListHis);


        // 处理在院病人住院信息数据
        handlePatInHos(patInHosListHis, patIdList);

        // 处理病人基本信息数据
        handlePatInf(patIdList);
    }


    private void handleOperSche1(String startTime, String endTime,
                                List<HisOperationSchedule> operScheList) {
        // 预约表处理集合定义
        List<HisOperationSchedule> uptOperScheList = new ArrayList<>();
        List<HisOperationSchedule> intOperScheList = new ArrayList<>();
        //Map<String, HisOperationSchedule> operScheLocalMap = getOperScheMap(startTime, endTime);
        String patId = null;
        String visitId = null;
        String scheId = null;

        List<HisOperationSchedule> realList = new ArrayList<>();

        // 声明手术名称信息、病人在院住院信息、病人基本信息集合
        List<HisScheduledOperationName> scheOperNameListHis = new ArrayList<>();
        List<HisPatsInHospital> patInHosListHis = new ArrayList<>();
        Set<String> patIdSet = new HashSet<>();
        HisOperationSchedule localBean;
        List<HisScheduledOperationName> operNameTemp;
        AtmOperationScheduleMid operMidTemp = new AtmOperationScheduleMid();
        AtmOperationScheduleMid operMidList;
        // 中间表处理集合定义
        List<AtmOperationScheduleMid> operMidUpt = new ArrayList<>();
        List<AtmOperationScheduleMid> operMidInt = new ArrayList<>();
        String shcheduleIdOwn = "";
        for (HisOperationSchedule openBean : operScheList) {
            // 根据His数据匹配中间表查询本地数据，做比对校验
            operMidTemp.setHisPatientId(openBean.getPatientId());
            operMidTemp.setHisVisitId(openBean.getVisitId());
            operMidTemp.setHisScheduleId(openBean.getScheduleId());
            operMidTemp.setScheduledDateTime(openBean.getScheduledDateTime());
            localBean = hisInfService.selOperScheMid(operMidTemp);

            patId = openBean.getPatientId();
            patIdSet.add(patId);
            visitId = openBean.getVisitId();
            scheId = openBean.getScheduleId();

            // 判断筛选预约申请信息
            if (localBean != null && localBean.getState() != null) {
                shcheduleIdOwn = localBean.getScheduleId();
                // 如果状态为0,才能进行更新
                if (Constants.OPER_SCHE_NEW == localBean.getState()) {
                    // 需要使用内部生成的scheduleId
                    openBean.setScheduleId(shcheduleIdOwn);
                    uptOperScheList.add(openBean);

                    operMidList = new AtmOperationScheduleMid();
                    operMidList.setAtmScheduleId(shcheduleIdOwn);
                    operMidList.setScheduledDateTime(openBean.getScheduledDateTime());
                    operMidList.setOperTime(DateUtils.dateTimeNow());
                    operMidUpt.add(operMidList);
                }else{
                    log.info("the oper sche not update");
                    log.info("his data:" + JSONObject.toJSONString(openBean));
                }
            } else {
                operMidList = new AtmOperationScheduleMid();
                operMidList.setAtmPatientId(patId);
                operMidList.setAtmVisitId(visitId);
                shcheduleIdOwn = IdUtils.fastSimpleUUID();
                operMidList.setAtmScheduleId(shcheduleIdOwn);
                operMidList.setHisPatientId(patId);
                operMidList.setHisVisitId(visitId);
                operMidList.setHisScheduleId(scheId);
                operMidList.setScheduledDateTime(openBean.getScheduledDateTime());
                operMidList.setOperTime(DateUtils.dateTimeNow());
                operMidInt.add(operMidList);

                // 重新替换内部生成的uui
                openBean.setScheduleId(shcheduleIdOwn);
                intOperScheList.add(openBean);
            }

            // 对应查询手术名称信息
            operNameTemp = getDynamicService().selScheOperNameHis(patId, visitId, scheId);

            if(!CollectionUtils.isEmpty(operNameTemp)){
                // 需要替换scheduleId,为内部生成ID
                for(HisScheduledOperationName operName : operNameTemp){
                    operName.setScheduleId(shcheduleIdOwn);
                }
            }
            scheOperNameListHis.addAll(operNameTemp);
        }

        // 处理麻醉本地库手术预约信息
        if (!CollectionUtils.isEmpty(uptOperScheList)) {
            hisInfService.uptOperScheLocal(uptOperScheList);
        }
        if (!CollectionUtils.isEmpty(intOperScheList)) {
            hisInfService.saveOperScheLocal(intOperScheList);
        }

        List<String> patIdList = new ArrayList<>(patIdSet);
        // 对应查询在院病人住院信息
        patInHosListHis = getDynamicService().selPatInHosHis(patIdList);

        // 处理手术名称数据
        handleScheOperName(scheOperNameListHis);

        // 处理在院病人住院信息数据
        handlePatInHos(patInHosListHis, patIdList);

        // 处理病人基本信息数据
        handlePatInf(patIdList);

        // 处理手术预约中间表数据
        if (!CollectionUtils.isEmpty(operMidUpt)) {
            hisInfService.uptOperMidLocal(operMidUpt);
        }
        if (!CollectionUtils.isEmpty(operMidInt)) {
            hisInfService.intOperMidLocal(operMidInt);
        }
    }

    private void emergencyHandle(HisOperationSchedule operSche, List<HisScheduledOperationName> operNameList) {
        // 循环拼接手术名称
        StringBuffer operNameAll = new StringBuffer("");
        String operNameStr = null;
        for (HisScheduledOperationName bean : operNameList) {
            operNameAll.append(bean.getOperation()).append(",");
        }

        if (operNameAll.length() > 0) {
            operNameStr = operNameAll.toString().substring(0, operNameAll.toString().length() - 1);
        }

        // 手术主表、计划表数据处理
        handleOperMaster(operSche, operNameStr);
    }

    private void handleOperMaster(HisOperationSchedule operSche, String operNameStr) {
        // 初始化手术master主表
        AnesOperationMaster master = new AnesOperationMaster();
        BeanUtils.copyProperties(operSche, master);
        master.setOperationName(operNameStr);
        master.setDiagAfterOperation(operSche.getDiagBeforeOperation());
        master.setOperId(operSche.getScheduleId());
        master.setVisitId(operSche.getVisitId());
        master.setOperStatus(Constants.OPERATION_STAGE_BEFORE);

        // 初始化手术计划表
        AnesAnesthesiaPlan plain = new AnesAnesthesiaPlan();
        BeanUtils.copyProperties(operSche, plain);
        plain.setOperationName(operNameStr);
        plain.setOperId(operSche.getScheduleId());
        plain.setWeight(operSche.getReserved5());
        plain.setHeight(operSche.getReserved6());
        plain.setVisitId(operSche.getVisitId());
        plain.setOperationClass(operSche.getOperationScale());

        AnesOperationMaster operMaster = hisInfService.selOperMasterLocal(operSche.getPatientId(),
                operSche.getVisitId(),
                operSche.getScheduleId());
        if (operMaster != null) {
            if (Constants.OPERATION_STAGE_BEFORE == operMaster.getOperStatus()) {
                // 术前，可以进行信息更新
                hisInfService.uptOperMaster(master);
                hisInfService.uptOperPlain(plain);
            }
        } else {
            hisInfService.intOperMaster(master);
            hisInfService.intOperPlain(plain);
        }
    }

    private void handleScheOperName(List<HisScheduledOperationName> scheOperName) {
        if (!CollectionUtils.isEmpty(scheOperName)) {
            // 先删除本地数据
            hisInfService.delScheOperName(scheOperName);
            // 插入新数据
            hisInfService.saveScheOperName(scheOperName);


            for (HisScheduledOperationName bean : scheOperName) {
                // 删除mongo数据
                hisInfService.delOperScheNameMongo(bean.getPatientId(), bean.getVisitId(), bean.getScheduleId());
            }
            // 保存mongo数据
            hisInfService.saveOperScheNameMongo(scheOperName);

            return;
        }
        log.info("no sche oper name data !");
    }

    private void handlePatInHos(List<HisPatsInHospital> patInHosListHis, List<String> patIdList) {
        if (!CollectionUtils.isEmpty(patInHosListHis)) {
            // 查询本地病人在院信息记录，用作比对
            List<HisPatsInHospital> patLocalList = hisInfService.selPatInHosLocal(patIdList);
            Map<String, HisPatsInHospital> patInfMap = new HashMap<>();
            for (HisPatsInHospital patInHosInf : patLocalList) {
                patInfMap.put(patInHosInf.getPatientId() + "|" + patInHosInf.getVisitId(),
                        patInHosInf);
            }

            List<HisPatsInHospital> uptList = new ArrayList<>();
            List<HisPatsInHospital> intList = new ArrayList<>();

            for (HisPatsInHospital patInf : patInHosListHis) {
                if (patInfMap.get(patInf.getPatientId() + "|" + patInf.getVisitId()) != null) {
                    uptList.add(patInf);
                } else {
                    intList.add(patInf);
                }

                // 删除本地Mongo数据库
                hisInfService.delPatInHosMongo(patInf);
            }

            // 真实操作本地库病人在院信息

            intList = intList.stream().collect(Collectors.collectingAndThen(Collectors.
                    toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getPatientId() + ";" + o.getVisitId()))), ArrayList::new));
            hisInfService.uptPatInHosLocal(uptList);
            hisInfService.savePatInHosLocal(intList);

            // 批量保存到mongo库中
            hisInfService.savePatInHosMongo(patInHosListHis);
        }
    }

    /**
     * 处理病人基本信息，同时将在院信息中最新的住院号字段值刷新到病人主表中
     *
     * @param patIdList 患者id集合
     */
    private void handlePatInf(List<String> patIdList) {

        // 根据patId列表查询本地病人基本信息
        List<HisPatMasterIndex> patLocalList = hisInfService.selPatInfLocal(patIdList);
        Map<String, HisPatMasterIndex> patInfMap = new HashMap<>();
        for (HisPatMasterIndex patInf : patLocalList) {
            patInfMap.put(patInf.getPatientId(), patInf);
        }

        List<HisPatMasterIndex> uptList = new ArrayList<>();
        List<HisPatMasterIndex> intList = new ArrayList<>();
        // 根据patId列表查询his病人基本信息
        List<HisPatMasterIndex> patHisList = getDynamicService().selPatInfHis(patIdList);
        for (HisPatMasterIndex patInf : patHisList) {
            // 将在院信息中的住院号设置到患者主表的住院号字段中
            if (patInfMap.get(patInf.getPatientId()) != null) {
                uptList.add(patInf);
            } else {
                intList.add(patInf);
            }
        }

        // 真实操作本地库病人基本信息信息
        intList = intList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(HisPatMasterIndex::getPatientId))), ArrayList::new));
        hisInfService.uptPatInfLocal(uptList);
        hisInfService.savePatInfLocal(intList);

        // 删除mongo数据
        hisInfService.delPatMasMongo(patIdList);

        // 保存mongo数据
        hisInfService.savePatMasMongo(patHisList);
    }

    /**
     * 根据时间段同步患者相关信息及预约信息
     *
     * @param startTime
     * @param endTime
     */
    public String syncSchedule(String startTime, String endTime) {

        // 默认进入时均先锁住，则可以调用同步程序，但是要先锁上，将标志设置为active
        scheduleSyncControllerService.uptSysCtlValue(Constants.SYS_CTL_SYNC_FLAG_CODE, Constants.SYS_CTL_SYNC_FLAG_VAL_ACTIVE);

        try {
            // 1、获取His手术申请预约信息
            List<HisOperationSchedule> operScheList = getDynamicService().selHisOpertSchele(null, null, startTime, endTime);

            if (CollectionUtils.isEmpty(operScheList)) {
                // 无预约手术信息，直接返回
                log.info("no operate schedule data ！");
                return Constants.SYNC_STATUS_SUCCESS;
            }

            // 利用set的特性去重
            Set<HisOperationSchedule> mHashSet = new LinkedHashSet<>(operScheList);
            operScheList = new ArrayList<>(mHashSet);
            operScheList = operScheList.stream().collect(Collectors.collectingAndThen(Collectors.
                    toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getPatientId() + ";" + o.getVisitId() + ";" + o.getScheduleId()))), ArrayList::new));


            // 2、更新申请手术mongo库数据
            hisInfService.delOperScheMongo(null, null, startTime, endTime);
            hisInfService.saveOperScheMongo(operScheList);

            /**
             * 处理预约手术申请信息数据
             * 转换为map,根据患者ID，住院次数，手术申请单条件进行判断，存在则更新，不存在则新增
             */
            handleOperSche(startTime, endTime, operScheList);

            return Constants.SYNC_STATUS_SUCCESS;
        } catch (Exception e){
            log.error("sync error ", e);
            return Constants.SYNC_STATUS_FIAL;
        } finally {
            // 操作完成或者异常时，要将标志还原，等待其他人调用
            scheduleSyncControllerService.uptSysCtlValue(Constants.SYS_CTL_SYNC_FLAG_CODE, Constants.SYS_CTL_SYNC_FLAG_VAL_SLEEP);
        }


    }

    @Transactional(rollbackFor = Exception.class)
    public void syncoperDic() {
        List<HisOperationDict> operDicList = getDynamicService().selOperDicHis();
        log.info("his手术名称数据-------"+operDicList.size());
        // 本地业务库数据更新
        hisInfService.delOperDic();
        hisInfService.saveOperDic(operDicList);

        // mongo临时库数据更新
        hisInfService.delOperDicMongo();
        hisInfService.saveOperDicMongo(operDicList);
    }

    public HisPatMasterIndex queryPatMaster(String patId) {
        List<HisPatMasterIndex> patInf = getDynamicService().selPatInfByConHis(patId);
        if (CollectionUtils.isEmpty(patInf)) {
            return null;
        }

        List<String> patIdList = new ArrayList<>();
        patIdList.add(patInf.get(0).getPatientId());
        hisInfService.delPatMasMongo(patIdList);
        hisInfService.savePatMasMongo(patInf);

        return patInf.get(0);
    }

    public HisPatsInHospital queryPatInHos(String patId, String inpNo) {
        List<HisPatsInHospital> patInHosList = getDynamicService().selPatInHosByConHis(patId, inpNo);
        if (CollectionUtils.isEmpty(patInHosList)) {
            return null;
        }
        HisPatsInHospital patInHos = patInHosList.get(0);

        hisInfService.delPatInHosMongo(patInHos);
        hisInfService.savePatInHosMongo(patInHosList);

        return patInHos;
    }

    public List<HisOperationSchedule> queryOperSche(String patId, String visitId, String startTime, String endTime) {

        List<HisOperationSchedule> operScheList = getDynamicService().selHisOpertSchele(patId, visitId, startTime,
                endTime);

        hisInfService.delOperScheMongo(patId, visitId, startTime, endTime);
        hisInfService.saveOperScheMongo(operScheList);

        return operScheList;
    }

    public List<HisScheduledOperationName> queryOperScheName(String patId, String visitId, String scheduleId) {

        List<HisScheduledOperationName> operScheNameList = getDynamicService().selScheOperNameHis(patId, visitId,
                scheduleId);

        hisInfService.delOperScheNameMongo(patId, visitId, scheduleId);
        hisInfService.saveOperScheNameMongo(operScheNameList);

        return operScheNameList;
    }

    /**
     * 同步病人申请检验数据信息
     */
    public void syncLabInf(String patId, String visitId, String inpNo) {
        if(Constants.SYNC_DATA_VIEW.equals(invokType)){
            visitId = null;
        }

//        if (StringUtils.isEmpty(inpNo)) {
//            log.info("----inpNo is null .no data------");
//            return;
//        }

        // 1、获取Lis人病人检验申请主记录数据
        List<LisLabTestMaster> labMasterList = getDynamicService().selLabMaster(patId, inpNo, visitId);

        if (CollectionUtils.isEmpty(labMasterList)) {
            log.info("no lab master data : {0},{1}", patId, inpNo);
            return;
        }
        //去重
        labMasterList = labMasterList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(LisLabTestMaster::getTestNo))), ArrayList::new));

        labMasterList.forEach(lab ->{
            lab.setPatientId(patId);
        });
        // 2、删除检验申请主记录mongo数据
        lisInfService.delLabMasterMongo(patId, visitId);

        // 3、保存检验申请主记录到mongo库中
        lisInfService.saveLabMasterMongo(labMasterList);

        // 4、根据条件删除本地检验申请主记录
        lisInfService.delLabMaster(patId, visitId);

        // 5、保存本地检验申请主记录
        lisInfService.saveLabMaster(labMasterList);

        // 6、获取检验详细数据
        List<String> testNoList = getTestNoList(labMasterList);
        List<LisLabResult> labResultList = getDynamicService().selLabResult(testNoList);

        // 7、删除检验申请详细记录mongo数据
        lisInfService.delLabResultMongo(testNoList);

        // 8、保存当前最新的数据
        lisInfService.saveLabResultMongo(labResultList);

        // 9、根据条件删除本地检验申请详细记录
        lisInfService.delLabResult(testNoList);

        // 10、保存本地检验详细记录
        lisInfService.saveLabResult(labResultList);
    }

    /**
     * 返回申请检验序号集合
     *
     * @param list
     * @return
     */
    private List<String> getTestNoList(List<LisLabTestMaster> list) {
        List<String> testNoList = new ArrayList<>();
        for (LisLabTestMaster bean : list) {
            testNoList.add(bean.getTestNo());
        }
        return testNoList;
    }

    private IHisInfQueryService getDynamicService() {
        String beanName = "";
        if (Constants.SYNC_DATA_VIEW.equals(invokType)){
            beanName = "viewQuery";
        } else if(Constants.SYNC_DATA_ZLGZWS.equals(invokType)){
            beanName = "zlGZWSQuery";
        } else if(Constants.SYNC_DATA_ZLCQHTTP.equals(invokType)){
            beanName = "zlCQHttpQuery";
        } else {
            // 不配类型，默认用视图
            beanName = "viewQuery";
        }

        return (IHisInfQueryService) SpringUtils.getBean(beanName);
    }

    /**
     *  判断当前同步程序是否正在运行
     * @return 1:正在同步，2:休眠中
     */
    public String getCurSyncStatus(){
        String value = scheduleSyncControllerService.selSysCtlValue(Constants.SYS_CTL_SYNC_FLAG_CODE);
        if(Constants.SYS_CTL_SYNC_FLAG_VAL_ACTIVE.equals(value)){
            return "1";
        }
        return "2";
    }


    public HisPatMasterIndex queryPatClinicMaster(String clinicNumber) {
        List<HisPatMasterIndex> patInf = getDynamicService().selPatInfByClinicNumber(clinicNumber);
        if (CollectionUtils.isEmpty(patInf)) {
            return null;
        }
        List<String> patIdList = new ArrayList<>();
        patIdList.add(patInf.get(0).getPatientId());
        hisInfService.delPatMasMongo(patIdList);
        hisInfService.savePatMasMongo(patInf);
        return patInf.get(0);
    }
}
